{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "---\n",
    "title: Introduction to Mojo\n",
    "sidebar_position: 1\n",
    "description: Introduction to Mojo's basic language features.\n",
    "---"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "At this point, you should have already set up the Mojo\n",
    "SDK and run [\"Hello\n",
    "world\"](/mojo/manual/get-started). Now let's talk about how\n",
    "to write Mojo code.\n",
    "\n",
    "You probably already know that Mojo is designed as a superset of Python. So if\n",
    "you know Python, then a lot of Mojo code will look familiar. However, Mojo\n",
    "is—first and foremost—designed for high-performance systems programming, with\n",
    "features like strong type checking, memory safety, next-generation compiler\n",
    "technologies, and more. As such, Mojo also has a lot in common with languages\n",
    "like C++ and Rust.\n",
    "\n",
    "Yet, we've designed Mojo to be flexible, so you can incrementally adopt\n",
    "systems-programming features like strong type checking as you see fit—Mojo does\n",
    "not *require* strong type checking.\n",
    "\n",
    "On this page, we'll introduce the essential Mojo syntax, so you can start\n",
    "coding quickly and understand other Mojo code you encounter. Subsequent\n",
    "sections in the Mojo Manual dive deeper into these topics, and links are\n",
    "provided below as appropriate.\n",
    "\n",
    "Let's get started! 🔥\n",
    "\n",
    ":::note\n",
    "\n",
    "Mojo is a young language and there are many [features still\n",
    "missing](/mojo/roadmap.html). As such, Mojo is currently **not** meant for\n",
    "beginners. Even this basics section assumes some programming experience.\n",
    "However, throughout the Mojo Manual, we try not to assume experience with any\n",
    "particular language.\n",
    "\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Mojo functions can be declared with either `fn` or `def`.\n",
    "\n",
    "The `fn` declaration enforces type-checking and memory-safe behaviors (Rust\n",
    "style), while `def` allows no type declarations and dynamic behaviors (Python\n",
    "style).\n",
    "\n",
    "For example, this `def` function doesn't require declaration of argument types\n",
    "or the return type:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def greet(name):\n",
    "    return \"Hello, \" + name + \"!\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While the same thing as an `fn` function requires that you specify the\n",
    "argument type and the return type like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fn greet2(name: String) -> String:\n",
    "    return \"Hello, \" + name + \"!\""
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Both functions have the same result, but the `fn` function provides\n",
    "compile-time checks to ensure the function receives and returns the correct\n",
    "types. Whereas, the `def` function might fail at runtime if it receives the\n",
    "wrong type.\n",
    "\n",
    "Currently, Mojo doesn't support top-level code in a `.mojo` (or `.🔥`) file, so\n",
    "every program must include a function named `main()` as the entry point.\n",
    "You can declare it with either `def` or `fn`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def main():\n",
    "   print(\"Hello, world!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ":::note\n",
    "\n",
    "You don't need a `main()` function when coding in the\n",
    "[REPL](/mojo/manual/get-started#run-code-in-the-repl) or in a\n",
    "[Jupyter\n",
    "notebook](https://github.com/modularml/mojo/tree/main/examples/notebooks#readme).\n",
    "\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For more details, see the page about\n",
    "[functions](/mojo/manual/functions.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Value ownership and argument mutability"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you're wondering whether function arguments are passed by value or\n",
    "passed by reference, the short answer is: `def` functions receive arguments\n",
    "\"by value\" and `fn` functions receive arguments \"by immutable reference.\"\n",
    "\n",
    "The longer short answer is that Mojo allows you to specify for each argument\n",
    "whether it should be passed by value (as `owned`), or whether it should be\n",
    "passed by reference (as `borrowed` for an immutable reference, or as `inout`\n",
    "for a mutable reference).\n",
    "\n",
    "This feature is entwined with Mojo's value ownership model, which protects you\n",
    "from memory errors by ensuring that only one variable \"owns\" a value at any\n",
    "given time (but allowing other variables to receive a reference to it).\n",
    "Ownership then ensures that the value is destroyed when the lifetime of the\n",
    "owner ends (and there are no outstanding references).\n",
    "\n",
    "But that's still a short answer, because going much further is a slippery slope\n",
    "into complexity that is out of scope for this section. For the complete\n",
    "answer, see the section about [value ownership](/mojo/manual/values/).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Variables"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can declare variables with the `var` keyword. Or, if your code is in a\n",
    "`def` function, you can omit the `var` (in an `fn` function, you must include\n",
    "the `var` keyword).\n",
    "\n",
    "For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "def do_math(x):\n",
    "    var y = x + x\n",
    "    y = y * y\n",
    "    print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Optionally, you can also declare a variable type like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def add_one(x):\n",
    "    var y: Int = 1\n",
    "    print(x + y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Even in an `fn` function, declaring the variable type is optional\n",
    "(only the argument and return types must be declared in `fn` functions).\n",
    "\n",
    "For more details, see the page about\n",
    "[variables](/mojo/manual/variables.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Structs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can build high-level abstractions for types (or \"objects\") as a `struct`. \n",
    "\n",
    "A `struct` in Mojo is similar to a `class` in Python: they both support\n",
    "methods, fields, operator overloading, decorators for metaprogramming, and so\n",
    "on. However, Mojo structs are completely static—they are bound at compile-time,\n",
    "so they do not allow dynamic dispatch or any runtime changes to the structure.\n",
    "(Mojo will also support Python-style classes in the future.)\n",
    "\n",
    "For example, here's a basic struct:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "struct MyPair:\n",
    "    var first: Int\n",
    "    var second: Int\n",
    "\n",
    "    fn __init__(inout self, first: Int, second: Int):\n",
    "        self.first = first\n",
    "        self.second = second\n",
    "\n",
    "    fn dump(self):\n",
    "        print(self.first, self.second)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And here's how you can use it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "fn use_mypair():\n",
    "    var mine = MyPair(2, 4)\n",
    "    mine.dump()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For more details, see the page about\n",
    "[structs](/mojo/manual/structs.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Traits\n",
    "\n",
    "A trait is like a template of characteristics for a struct. If you want to\n",
    "create a struct with the characteristics defined in a trait, you must implement\n",
    "each characteristic (such as each method). Each characteristic in a trait is a\n",
    "\"requirement\" for the struct, and when your struct implements each requirement,\n",
    "it's said to \"conform\" to the trait.\n",
    "\n",
    "Currently, the only characteristics that traits can define are method signatures. Also, traits\n",
    "currently cannot implement default behaviors for methods.\n",
    "\n",
    "Using traits allows you to write generic functions that can accept any type\n",
    "that conforms to a trait, rather than accept only specific types.\n",
    "\n",
    "For example, here's how you can create a trait (notice the function is not\n",
    "implemented):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "trait SomeTrait:\n",
    "    fn required_method(self, x: Int): ..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And here's how to create a struct that conforms to the trait:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "@value\n",
    "struct SomeStruct(SomeTrait):\n",
    "    fn required_method(self, x: Int):\n",
    "        print(\"hello traits\", x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, here's a function that uses the trait as an argument type (instead of the\n",
    "struct type):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "fn fun_with_traits[T: SomeTrait](x: T):\n",
    "    x.required_method(42)\n",
    "\n",
    "fn use_trait_function():\n",
    "    var thing = SomeStruct()\n",
    "    fun_with_traits(thing)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ":::note\n",
    "\n",
    "You're probably wondering about the square brackets on `fun_with_traits()`.\n",
    "These aren't function _arguments_ (which go in parentheses); these are function\n",
    "_parameters_, which we'll explain next.\n",
    "\n",
    ":::\n",
    "\n",
    "Without traits, the `x` argument in `fun_with_traits()` would have to declare a\n",
    "specific type that implements `required_method()`, such as `SomeStruct`\n",
    "(but then the function would accept only that type). With traits, the function\n",
    "can accept any type for `x` as long as it conforms to (it \"implements\")\n",
    "`SomeTrait`. Thus, `fun_with_traits()` is known as a \"generic function\" because\n",
    "it accepts a _generalized_ type instead of a specific type.\n",
    "\n",
    "For more details, see the page about [traits](/mojo/manual/traits.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Parameterization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In Mojo, a parameter is a compile-time variable that becomes a runtime\n",
    "constant, and it's declared in square brackets on a function or struct.\n",
    "Parameters allow for compile-time metaprogramming, which means you can generate\n",
    "or modify code at compile time.\n",
    "\n",
    "Many other languages use \"parameter\" and \"argument\" interchangeably, so be\n",
    "aware that when we say things like \"parameter\" and \"parametric function,\" we're\n",
    "talking about these compile-time parameters. Whereas, a function \"argument\" is\n",
    "a runtime value that's declared in parentheses.\n",
    "\n",
    "Parameterization is a complex topic that's covered in much more detail in the\n",
    "[Metaprogramming](/mojo/manual/parameters/) section, but we want to break the\n",
    "ice just a little bit here. To get you started, let's look at a parametric\n",
    "function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "fn repeat[count: Int](msg: String):\n",
    "    for i in range(count):\n",
    "        print(msg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This function has one parameter of type `Int` and one argument of type\n",
    "`String`. To call the function, you need to specify both the parameter and the\n",
    "argument:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "fn call_repeat():\n",
    "    repeat[3](\"Hello\")\n",
    "    # Prints \"Hello\" 3 times"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By specifying `count` as a parameter, the Mojo compiler is able to optimize the\n",
    "function because this value is guaranteed to not change at runtime. The\n",
    "compiler effectively generates a unique version of the `repeat()` function that\n",
    "repeats the message only 3 times. This makes the code more performant because\n",
    "there's less to compute at runtime.\n",
    "\n",
    "Similarly, you can define a struct with parameters, which effectively allows\n",
    "you to define variants of that type at compile-time, depending on the parameter\n",
    "values.\n",
    "\n",
    "For more detail on parameters, see the section on\n",
    "[Metaprogramming](/mojo/manual/parameters/)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Blocks and statements"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Code blocks such as functions, conditions, and loops are defined\n",
    "with a colon followed by indented lines. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loop():\n",
    "    for x in range(5):\n",
    "        if x % 2 == 0:\n",
    "            print(x)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can use any number of spaces or tabs for your indentation (we prefer 4\n",
    "spaces).\n",
    "\n",
    "All code statements in Mojo end with a newline. However, statements can span\n",
    "multiple lines if you indent the following lines. For example, this long string\n",
    "spans two lines:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_line():\n",
    "    long_text = \"This is a long line of text that is a lot easier to read if\"\n",
    "                \" it is broken up across two lines instead of one long line.\"\n",
    "    print(long_text)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And you can chain function calls across lines:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_hello():\n",
    "    text = String(\",\")\n",
    "          .join(\"Hello\", \" world!\")\n",
    "    print(text)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code comments\n",
    "\n",
    "You can create a one-line comment using the hash `#` symbol:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is a comment. The Mojo compiler ignores this line."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Comments may also follow some code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "var message = \"Hello, World!\" # This is also a valid comment"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can instead write longer comments across many lines using triple quotes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "This is also a comment, but it's easier to write across\n",
    "many lines, because each line doesn't need the # symbol.\n",
    "\"\"\""
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Triple quotes is the preferred method of writing API documentation. For example:\n",
    "\n",
    "```mojo\n",
    "fn print(x: String):\n",
    "    \"\"\"Prints a string.\n",
    "\n",
    "    Args:\n",
    "        x: The string to print.\n",
    "    \"\"\"\n",
    "    ...\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Documenting your code with these kinds of comments (known as \"docstrings\")\n",
    "is a topic we've yet to fully specify, but you can generate an API reference\n",
    "from docstrings using the [`mojo doc` command](/mojo/cli/doc.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Python integration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Mojo is not yet a full superset of Python, but we've built a mechanism to import\n",
    "Python modules as-is, so you can leverage existing Python code right away.\n",
    "\n",
    "For example, here's how you can import and use NumPy (you must have Python\n",
    "`numpy` installed):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from python import Python\n",
    "\n",
    "fn use_numpy() raises:\n",
    "    var np = Python.import_module(\"numpy\")\n",
    "    var ar = np.arange(15).reshape(3, 5)\n",
    "    print(ar)\n",
    "    print(ar.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ":::note\n",
    "\n",
    "**Note:** You must have the Python module (such as `numpy`) installed already.\n",
    "\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For more details, see the page about\n",
    "[Python integration](/mojo/manual/python/)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next steps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Hopefully this page has given you enough information to start experimenting with\n",
    "Mojo, but this is only touching the surface of what's available in Mojo.\n",
    "\n",
    "If you're in the mood to read more, continue through each page of this\n",
    "Mojo Manual using the buttons at the bottom of each page—the next page from\n",
    "here is [Functions](/mojo/manual/functions.html).\n",
    "\n",
    "Otherwise, here are some other resources to check out:\n",
    "\n",
    "- If you want to experiment with some code, clone [the Mojo\n",
    "repo](https://github.com/modularml/mojo/) to try our code examples:\n",
    "\n",
    "  ```sh\n",
    "  git clone https://github.com/modularml/mojo.git\n",
    "  ```\n",
    "\n",
    "  In addition to several `.mojo` examples, the repo includes [Jupyter\n",
    "  notebooks](https://github.com/modularml/mojo/tree/main/examples/notebooks#readme)\n",
    "  that teach advanced Mojo features.\n",
    "\n",
    "- To see all the available Mojo APIs, check out the [Mojo standard library\n",
    "  reference](/mojo/lib.html)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Mojo",
   "language": "mojo",
   "name": "mojo-jupyter-kernel"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "mojo"
   },
   "file_extension": ".mojo",
   "mimetype": "text/x-mojo",
   "name": "mojo"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
